<html>
<head>
    <title>Canvas tutorial</title>
    <style type="text/css">
        canvas {
            border: 1px solid black;
        }
    </style>
</head>
<canvas id="tutorial" width="300" height="300"></canvas>

<!-- <img src="https://img2.baidu.com/it/u=389602923,1645280233&fm=26&fmt=auto" alt="" width="300"><br>
<canvas id="imageCanvas" width="600" height="400"></canvas> -->
</body>
<script type="text/javascript">
    // function draw(){
    //     // #region  初始化，创建一个2D canvas实例
    //     var canvas = document.getElementById('tutorial');
    //     if(!canvas.getContext) return;
    //     var ctx = canvas.getContext("2d");
    //     // #endregion


    //     // #region  矩形
    //     // ctx.fillRect(10, 10, 100, 50);  //绘制矩形,填充的默认颜色为黑色
    //     // ctx.strokeRect(10, 70, 100, 50);  //绘制矩形边框
    //     // ctx.clearRect(15, 15, 50, 25);
    //     // #endregion


    //     // #region  路径（线条）
    //     // ctx.beginPath(); //新建一条path
    //     // ctx.moveTo(50, 50); //把画笔移动到指定的坐标
    //     // ctx.lineTo(200, 50);  //绘制一条从当前位置到指定坐标(200, 50)的直线.
    //     // //闭合路径。会拉一条从当前点到path起始点的直线。如果当前点与起始点重合，则什么都不做
    //     // ctx.closePath();
    //     // ctx.stroke(); //绘制路径。
    //     // #endregion


    //     // #region  路径（三角形）
    //     // ctx.beginPath();
    //     // ctx.moveTo(50, 50);
    //     // ctx.lineTo(200, 50);
    //     // ctx.lineTo(200, 200);
    //     // ctx.closePath(); //虽然我们只绘制了两条线段，但是closePath会closePath，仍然是一个3角形
    //     // ctx.stroke(); //描边。stroke不会自动closePath()
    //     // ctx.fill(); //填充闭合区域。如果path没有闭合，则fill()会自动闭合路径。
    //     // #endregion


    //     // #region  圆弧
    //     // ctx.beginPath();
    //     // ctx.arc(100, 100, 50, 0, (Math.PI/180)*360, false); // x轴坐标：100；y轴坐标：100；半径：50；弧度开始：0；弧度结束：radians=(Math.PI/180)*degrees（角度转换成弧度）;布尔值：true表示逆时针，false表示顺时针(默认是顺时针)。
    //     // ctx.stroke();

    //     // ctx.beginPath();
    //     // ctx.arc(50, 50, 40, 0, Math.PI / 2, false);
    //     // ctx.stroke();

    //     // ctx.beginPath();
    //     // ctx.arc(150, 50, 40, 0, Math.PI * 1.5, true);
    //     // // ctx.closePath();
    //     // ctx.stroke();

    //     // ctx.beginPath();
    //     // ctx.arc(50, 150, 40, -Math.PI / 2, Math.PI / 2, false);
    //     // ctx.fill();

    //     // ctx.beginPath();
    //     // ctx.arc(150, 150, 40, 0, Math.PI, false);
    //     // ctx.fill();
    //     // #endregion


    //     // #region  贝塞尔曲线
    //     // 二次贝塞尔曲线
    //     // ctx.beginPath();
    //     // ctx.moveTo(10, 200); //起始点
    //     // var cp1x = 200, cp1y = 100;  //控制点
    //     // var x = 200, y = 200; // 结束点
    //     // //绘制二次贝塞尔曲线
    //     // ctx.quadraticCurveTo(cp1x, cp1y, x, y);
    //     // ctx.stroke();
        
    //     // ctx.beginPath();
    //     // ctx.rect(10, 200, 10, 10);
    //     // ctx.rect(cp1x, cp1y, 10, 10);
    //     // ctx.rect(x, y, 10, 10);
    //     // ctx.fill();


    //     // 三次贝塞尔曲线
    //     // ctx.beginPath();
    //     // ctx.moveTo(40, 200); //起始点
    //     // var cp1x = 40, cp1y = 20;  //控制点1
    //     // var cp2x = 200, cp2y = 120;  //控制点2
    //     // var x = 200, y = 200; // 结束点
    //     // //绘制二次贝塞尔曲线
    //     // ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
    //     // ctx.stroke();

    //     // ctx.beginPath();
    //     // ctx.rect(40, 200, 10, 10);
    //     // ctx.rect(cp1x, cp1y, 10, 10);
    //     // ctx.rect(cp2x, cp2y, 10, 10);
    //     // ctx.rect(x, y, 10, 10);
    //     // ctx.fill();
    //     // #endregion


    //     // #region  颜色
    //     // 实心
    //     // for (var i = 0; i < 6; i++){
    //     //   for (var j = 0; j < 6; j++){
    //     //     ctx.fillStyle = 'rgb(' + Math.floor(255 - 42.5 * i) + ',' + Math.floor(255 - 42.5 * j) + ',0)';
    //     //     ctx.fillRect(j * 50, i * 50, 50, 50);
    //     //   }
    //     // }

    //     // 
    //     // for (var i = 0; i < 6; i++){
    //     //     for (var j = 0; j < 6; j++){
    //     //         ctx.strokeStyle = `rgb(${randomInt(0, 255)},${randomInt(0, 255)},${randomInt(0, 255)})`;
    //     //         ctx.strokeRect(j * 50, i * 50, 40, 40);
    //     //     }
    //     // }
    //     // #endregion

        
    //     // #region  设置线条宽度
    //     // ctx.beginPath();
    //     // ctx.moveTo(10, 10);
    //     // ctx.lineTo(100, 10);
    //     // ctx.lineWidth = 10;
    //     // ctx.stroke();

    //     // ctx.beginPath();
    //     // ctx.moveTo(110, 10);
    //     // ctx.lineTo(160, 10)
    //     // ctx.lineWidth = 20;
    //     // ctx.stroke()
    //     // #endregion


    //     // #region  设置线条末端样式  
    //     /*  
    //         butt：线段末端以方形结束
    //         round：线段末端以圆形结束
    //         square：线段末端以方形结束，但是增加了一个宽度和线段相同，高度是线段厚度一半的矩形区域。
    //     */
    //     // var lineCaps = ["butt", "round", "square"];
    //     // for (var i = 0; i < 3; i++){
    //     //     ctx.beginPath();
    //     //     ctx.moveTo(20 + 30 * i, 30);
    //     //     ctx.lineTo(20 + 30 * i, 100);
    //     //     ctx.lineWidth = 20;
    //     //     ctx.lineCap = lineCaps[i];
    //     //     ctx.stroke();
    //     // }

    //     // ctx.beginPath();
    //     // ctx.moveTo(0, 30);
    //     // ctx.lineTo(300, 30);

    //     // ctx.moveTo(0, 100);
    //     // ctx.lineTo(300, 100)

    //     // ctx.strokeStyle = "red";
    //     // ctx.lineWidth = 1;
    //     // ctx.stroke();
    //     // #endregion


    //     // #region  同一个path内，设定线条与线条间接合处的样式
    //     /* 
    //       round：通过填充一个额外的，圆心在相连部分末端的扇形，绘制拐角的形状。 圆角的半径是线段的宽度。
    //       bevel：在相连部分的末端填充一个额外的以三角形为底的区域， 每个部分都有各自独立的矩形拐角。
    //       miter(默认)：通过延伸相连部分的外边缘，使其相交于一点，形成一个额外的菱形区域。
    //     */
    //     // var lineJoin = ['round', 'bevel', 'miter'];
    //     // ctx.lineWidth = 20;

    //     // for (var i = 0; i < lineJoin.length; i++){
    //     //     ctx.lineJoin = lineJoin[i];
    //     //     ctx.beginPath();
    //     //     ctx.moveTo(50, 50 + i * 50);
    //     //     ctx.lineTo(100, 100 + i * 50);
    //     //     ctx.lineTo(150, 50 + i * 50);
    //     //     ctx.lineTo(200, 100 + i * 50);
    //     //     ctx.lineTo(250, 50 + i * 50);
    //     //     ctx.stroke();
    //     // }
    //     // #endregion


    //     // #region 虚线  
    //     // ctx.setLineDash([20,20]);  // [实线长度, 间隙长度]
    //     // ctx.lineDashOffset = 8; // 偏移量
    //     // ctx.strokeRect(50, 50, 210, 210);
    //     // /* getLineDash():返回一个包含当前虚线样式，长度为非负偶数的数组。 */
    //     // console.log(ctx.getLineDash())  // [5, 10]
    //     // #endregion


    //     // #region  绘制文本
    //     // ctx.font = "100px sans-serif"
    //     // ctx.fillText("天若有情", 10, 100);
    //     // ctx.strokeText("天若有情", 10, 200)
    //     // #endregion
    

    //     // #region  虚线
    //     /* 
    //       fillText(text, x, y [, maxWidth])
    //         在指定的(x,y)位置填充指定的文本，绘制的最大宽度是可选的.
    //       strokeText(text, x, y [, maxWidth])
    //         在指定的(x,y)位置绘制文本边框，绘制的最大宽度是可选的.

    //       添加样式：
    //       1、font = value
    //         当前我们用来绘制文本的样式。这个字符串使用和 CSS font属性相同的语法. 默认的字体是 10px sans-serif。
    //       2、textAlign = value
    //         文本对齐选项. 可选的值包括：start, end, left, right or center. 默认值是 start。
    //       3、textBaseline = value
    //         基线对齐选项，可选的值包括：top, hanging, middle, alphabetic, ideographic, bottom。默认值是 alphabetic。
    //       4、direction = value
    //         文本方向。可能的值包括：ltr, rtl, inherit。默认值是 inherit。
    //     */
    //     // ctx.font = "50px sans-serif"
    //     // ctx.textAlign = "start"
    //     // ctx.textBaseline = "alphabetic"
    //     // ctx.direction = "inherit"
    //     // ctx.fillText("天若有情", 10, 100);
    //     // ctx.strokeText("天若有情", 10, 200)
    //     // #endregion


    //     // #region  绘制图片
    //     /* drawImage(image, x, y, width, height) */
    //     // var canvas = document.getElementById('imageCanvas');
    //     // if (!canvas.getContext) return;
    //     // var ctx = canvas.getContext("2d");
    //     // var img = document.querySelector("img");
    //     // img.onload = function(){
    //     //   console.dir(img)
    //     //   ctx.drawImage(img, 0, 0,img.width,img.height);
    //     // }
    //     // #endregion


    //     // #region  状态的保存和恢复
    //     /**
    //       save()和restore():
    //         save 和 restore 方法是用来保存和恢复 canvas 状态的，都没有参数。
    //       ​  Canvas 的状态就是当前画面应用的所有样式和变形的一个快照。
    //       1、关于 save()
    //         Canvas状态存储在栈中，每当save()方法被调用后，当前的状态就被推送到栈中保存。一个绘画状态包括：
    //         当前应用的变形（即移动，旋转和缩放）
    //           strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit,
    //           shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation 的值
    //         当前的裁切路径（clipping path）
    //         可以调用任意多次 save方法。(类似数组的push())
    //       2、关于restore()
    //         每一次调用 restore 方法，上一个保存的状态就从栈中弹出，所有设定都恢复。(类似数组的pop())
    //     */
    //     // ctx.fillRect(0, 0, 150, 150);   // 使用默认设置绘制一个矩形
    //     // ctx.save();                  // 保存默认状态

    //     // ctx.fillStyle = 'red'       // 在原有配置基础上对颜色做改变
    //     // ctx.fillRect(15, 15, 120, 120); // 使用新的设置绘制一个矩形

    //     // ctx.save();                  // 保存当前状态
    //     // ctx.fillStyle = '#FFF'       // 再次改变颜色配置
    //     // ctx.fillRect(30, 30, 90, 90);   // 使用新的配置绘制一个矩形

    //     // ctx.restore();               // 重新加载之前的颜色状态
    //     // ctx.fillRect(45, 45, 60, 60);   // 使用上一次的配置绘制一个矩形

    //     // ctx.restore();               // 加载默认颜色配置
    //     // ctx.fillRect(60, 60, 30, 30);   // 使用加载的配置绘制一个矩形
    //     // #endregion
    
    
    //     // #region  移动translate
    // // ​    ctx.save(); //保存坐原点平移之前的状态
    // //     ctx.translate(100, 100);
    // //     ctx.strokeRect(0, 0, 100, 100)
    // //     ctx.restore(); //恢复到最初状态
    // //     ctx.translate(220, 220);
    // //     ctx.fillRect(0, 0, 100, 100)
    //     // #endregion

    //   // #region  圆头像
    //   // var img = new Image();   // 创建一个<img>元素
    //   // img.src = 'https://img2.baidu.com/it/u=389602923,1645280233&fm=26&fmt=auto'; // 设置图片源地址
    //   // img.onload = function(){
    //   //   ctx.beginPath();
    //   //   ctx.arc(20+250/2, 20+250/2, 250/2, 0, (Math.PI/180)*360, false); // x轴坐标：100；y轴坐标：100；半径：50；弧度开始：0；弧度结束：radians=(Math.PI/180)*degrees（角度转换成弧度）;布尔值：true表示逆时针，false表示顺时针(默认是顺时针)。;
    //   //   ctx.stroke();
    //   //   ctx.clip();
    //   //   ctx.drawImage(img,20,20,250,250);
    //   // }
    //   // #endregion

    //   // #region  模拟圆角border-raduis
    //   // var img = new Image();   // 创建一个<img>元素
    //   // img.src = 'https://img2.baidu.com/it/u=389602923,1645280233&fm=26&fmt=auto'; // 设置图片源地址
    //   // img.onload = function(){
    //   //   /* 头像 */
    //   //   let headImgwidth = 50
    //   //   let headImgX = 20
    //   //   let headImgY = 20

    //   //   ctx.save()
    //   //   ctx.beginPath();  // 开启路径
    //   //   ctx.arc(headImgX+headImgwidth/2, headImgY+headImgwidth/2, headImgwidth/2, 0, (Math.PI/180)*360, false); // 以头像中心点绘制圆
    //   //   // ctx.stroke();
    //   //   ctx.closePath();  // 闭合路径
    //   //   ctx.clip(); // 裁切
    //   //   ctx.drawImage(img,headImgX,headImgY,headImgwidth,headImgwidth); // 绘制头像
    //   //   ctx.restore()

    //   //   /* 图片 */
    //   //   let borderRadius = 10
    //   //   let imgWidth = 200
    //   //   let imgHeight = 170
    //   //   let imgX = 60
    //   //   let imgY = 90

    //   //   ctx.save()
        
    //   //   ctx.beginPath();  // 开始绘制图像的路径
    //   //   // 左上角
    //   //   ctx.moveTo(imgX,imgY+borderRadius)
    //   //   ctx.arcTo(imgX,imgY,imgX+borderRadius,imgY,borderRadius)
    //   //   // 右上角
    //   //   ctx.lineTo(imgX+imgWidth-borderRadius,imgY)
    //   //   ctx.arcTo(imgX+imgWidth,imgY,imgX+imgWidth,imgY+borderRadius,borderRadius)
    //   //   // 右下角
    //   //   ctx.lineTo(imgX+imgWidth,imgY+imgHeight-borderRadius)
    //   //   ctx.arcTo(imgX+imgWidth,imgY+imgHeight,imgX+imgWidth-borderRadius,imgY+imgHeight,borderRadius)
    //   //   // 左下角
    //   //   ctx.lineTo(imgX+borderRadius,imgY+imgHeight)
    //   //   ctx.arcTo(imgX,imgY+imgHeight,imgX,imgY+imgHeight-borderRadius,borderRadius)
    //   //   ctx.lineTo(imgX,imgY+borderRadius)
        
    //   //   ctx.closePath(); // 关闭路径
    //   //   ctx.clip();
    //   //   // ctx.stroke();
    //   //   ctx.drawImage(img,imgX,imgY,imgWidth,imgHeight);
    //   //   ctx.restore()
    //   // }
    //   // #endregion
    // }

    // function randomInt(from, to){
    //     return parseInt(Math.random() * (to - from + 1) + from);
    // }
    // draw();

    // #region 太阳系
    // let sun;
    // let earth;
    // let moon;
    // let ctx;
    // function init(){
    //   sun = new Image();
    //   earth = new Image();
    //   moon = new Image();
    //   sun.src = "https://img2.baidu.com/it/u=389602923,1645280233&fm=26&fmt=auto";
    //   earth.src = "https://img2.baidu.com/it/u=389602923,1645280233&fm=26&fmt=auto";
    //   moon.src = "https://img2.baidu.com/it/u=389602923,1645280233&fm=26&fmt=auto";

    //   let canvas = document.querySelector("#tutorial");
    //   ctx = canvas.getContext("2d");

    //   sun.onload = function (){
    //       draw()
    //   }
    // }
    // init();
    // function draw(){
    //   debugger
    //   ctx.clearRect(0, 0, 300, 300); // 清空所有的内容
    //   /*绘制 太阳*/
    //   ctx.drawImage(sun, 0, 0, 300, 300);

    //   ctx.save();
    //   ctx.translate(150, 150);

    //   //绘制earth轨道
    //   ctx.beginPath();
    //   ctx.strokeStyle = "rgba(255,255,0,0.5)";
    //   ctx.arc(0, 0, 100, 0, 2 * Math.PI)
    //   ctx.stroke()

    //   let time = new Date();
    //   //绘制地球
    //   ctx.rotate(2 * Math.PI / 60 * time.getSeconds() + 2 * Math.PI / 60000 * time.getMilliseconds())
    //   ctx.translate(100, 0);
    //   ctx.drawImage(earth, -12, -12)

    //   //绘制月球轨道
    //   ctx.beginPath();
    //   ctx.strokeStyle = "rgba(255,255,255,.3)";
    //   ctx.arc(0, 0, 40, 0, 2 * Math.PI);
    //   ctx.stroke();

    //   //绘制月球
    //   ctx.rotate(2 * Math.PI / 6 * time.getSeconds() + 2 * Math.PI / 6000 * time.getMilliseconds());
    //   ctx.translate(40, 0);
    //   ctx.drawImage(moon, -3.5, -3.5);
    //   ctx.restore();

    //   requestAnimationFrame(draw);
    // }
    // #endregion

    // #region 时钟
    // init();

    // function init(){
    //     let canvas = document.querySelector("#solar");
    //     let ctx = canvas.getContext("2d");
    //     draw(ctx);
    // }

    // function draw(ctx){
    //     requestAnimationFrame(function step(){
    //         drawDial(ctx); //绘制表盘
    //         drawAllHands(ctx); //绘制时分秒针
    //         requestAnimationFrame(step);
    //     });
    // }
    // /*绘制时分秒针*/
    // function drawAllHands(ctx){
    //     let time = new Date();

    //     let s = time.getSeconds();
    //     let m = time.getMinutes();
    //     let h = time.getHours();
        
    //     let pi = Math.PI;
    //     let secondAngle = pi / 180 * 6 * s;  //计算出来s针的弧度
    //     let minuteAngle = pi / 180 * 6 * m + secondAngle / 60;  //计算出来分针的弧度
    //     let hourAngle = pi / 180 * 30 * h + minuteAngle / 12;  //计算出来时针的弧度

    //     drawHand(hourAngle, 60, 6, "red", ctx);  //绘制时针
    //     drawHand(minuteAngle, 106, 4, "green", ctx);  //绘制分针
    //     drawHand(secondAngle, 129, 2, "blue", ctx);  //绘制秒针
    // }
    // /*绘制时针、或分针、或秒针
    //  * 参数1：要绘制的针的角度
    //  * 参数2：要绘制的针的长度
    //  * 参数3：要绘制的针的宽度
    //  * 参数4：要绘制的针的颜色
    //  * 参数4：ctx
    //  * */
    // function drawHand(angle, len, width, color, ctx){
    //     ctx.save();
    //     ctx.translate(150, 150); //把坐标轴的远点平移到原来的中心
    //     ctx.rotate(-Math.PI / 2 + angle);  //旋转坐标轴。 x轴就是针的角度
    //     ctx.beginPath();
    //     ctx.moveTo(-4, 0);
    //     ctx.lineTo(len, 0);  // 沿着x轴绘制针
    //     ctx.lineWidth = width;
    //     ctx.strokeStyle = color;
    //     ctx.lineCap = "round";
    //     ctx.stroke();
    //     ctx.closePath();
    //     ctx.restore();
    // }
    
    // /*绘制表盘*/
    // function drawDial(ctx){
    //     let pi = Math.PI;
        
    //     ctx.clearRect(0, 0, 300, 300); //清除所有内容
    //     ctx.save();

    //     ctx.translate(150, 150); //一定坐标原点到原来的中心
    //     ctx.beginPath();
    //     ctx.arc(0, 0, 148, 0, 2 * pi); //绘制圆周
    //     ctx.stroke();
    //     ctx.closePath();

    //     for (let i = 0; i < 60; i++){//绘制刻度。
    //         ctx.save();
    //         ctx.rotate(-pi / 2 + i * pi / 30);  //旋转坐标轴。坐标轴x的正方形从 向上开始算起
    //         ctx.beginPath();
    //         ctx.moveTo(110, 0);
    //         ctx.lineTo(140, 0);
    //         ctx.lineWidth = i % 5 ? 2 : 4;
    //         ctx.strokeStyle = i % 5 ? "blue" : "red";
    //         ctx.stroke();
    //         ctx.closePath();
    //         ctx.restore();
    //     }
    //     ctx.restore();
    // }
    // // #endregion
    // init();

    // function init(){
    //     let canvas = document.querySelector("#tutorial");
    //     let ctx = canvas.getContext("2d");
    //     draw(ctx);
    // }

    // function draw(ctx){
    //     requestAnimationFrame(function step(){
    //         drawDial(ctx); //绘制表盘
    //         drawAllHands(ctx); //绘制时分秒针
    //         requestAnimationFrame(step);
    //     });
    // }
    // /*绘制时分秒针*/
    // function drawAllHands(ctx){
    //     let time = new Date();

    //     let s = time.getSeconds();
    //     let m = time.getMinutes();
    //     let h = time.getHours();
        
    //     let pi = Math.PI;
    //     let secondAngle = pi / 180 * 6 * s;  //计算出来s针的弧度
    //     let minuteAngle = pi / 180 * 6 * m + secondAngle / 60;  //计算出来分针的弧度
    //     let hourAngle = pi / 180 * 30 * h + minuteAngle / 12;  //计算出来时针的弧度

    //     drawHand(hourAngle, 60, 6, "red", ctx);  //绘制时针
    //     drawHand(minuteAngle, 106, 4, "green", ctx);  //绘制分针
    //     drawHand(secondAngle, 129, 2, "blue", ctx);  //绘制秒针
    // }
    // /*绘制时针、或分针、或秒针
    //  * 参数1：要绘制的针的角度
    //  * 参数2：要绘制的针的长度
    //  * 参数3：要绘制的针的宽度
    //  * 参数4：要绘制的针的颜色
    //  * 参数4：ctx
    //  * */
    // function drawHand(angle, len, width, color, ctx){
    //     ctx.save();
    //     ctx.translate(150, 150); //把坐标轴的远点平移到原来的中心
    //     ctx.rotate(-Math.PI / 2 + angle);  //旋转坐标轴。 x轴就是针的角度
    //     ctx.beginPath();
    //     ctx.moveTo(-4, 0);
    //     ctx.lineTo(len, 0);  // 沿着x轴绘制针
    //     ctx.lineWidth = width;
    //     ctx.strokeStyle = color;
    //     ctx.lineCap = "round";
    //     ctx.stroke();
    //     ctx.closePath();
    //     ctx.restore();
    // }
    
    // /*绘制表盘*/
    // function drawDial(ctx){
    //     let pi = Math.PI;
        
    //     ctx.clearRect(0, 0, 300, 300); //清除所有内容
    //     ctx.save();

    //     ctx.translate(150, 150); //一定坐标原点到原来的中心
    //     ctx.beginPath();
    //     ctx.arc(0, 0, 148, 0, 2 * pi); //绘制圆周
    //     ctx.stroke();
    //     ctx.closePath();

    //     for (let i = 0; i < 60; i++){//绘制刻度。
    //         ctx.save();
    //         ctx.rotate(-pi / 2 + i * pi / 30);  //旋转坐标轴。坐标轴x的正方形从 向上开始算起
    //         ctx.beginPath();
    //         ctx.moveTo(110, 0);
    //         ctx.lineTo(140, 0);
    //         ctx.lineWidth = i % 5 ? 2 : 4;
    //         ctx.strokeStyle = i % 5 ? "blue" : "red";
    //         ctx.stroke();
    //         ctx.closePath();
    //         ctx.restore();
    //     }
    //     ctx.restore();
    // }
    // #endregion

    let canvas = document.querySelector("#tutorial");
    let ctx = canvas.getContext("2d");
    // ctx.beginPath();
    // ctx.translate(50, 50);
    // //创建渐变圆环
    // var grd = ctx.createLinearGradient(0, 0, 200, 0);
    // //镜像渐变
    // //    createRadialGradient(x,y,r,x1,y1,r1)
    // grd.addColorStop(0.5, 'red');
    // //    grd.addColorStop(0.5,'green');
    // //    grd.addColorStop(0.8,'red');
    // grd.addColorStop(1, 'blue'); //填充渐变
    // ctx.lineWidth = 8;
    // ctx.strokeStyle = grd;
    // ctx.fillStyle = grd;
    // //沿着 100,100 位圆心，画圆
    // ctx.arc(100, 100, 50, 0, 360 * Math.PI / 180, true); //路径
    // //    ctx.stroke(); // 圆环
    // ctx.fill(); //实心圆

    // function drawLine(stepx, stepy) {
    //   //样式
    //   ctx.lineWidth = 0.5;
    //   ctx.strokeStyle = 'green';
    //   //绘制竖线
    //   for (var i = stepx + 0.5; i < canvas.width; i += stepx) {
    //     ctx.beginPath(); //新的一条路径
    //     ctx.moveTo(i, 0);
    //     ctx.lineTo(i, canvas.height);
    //     ctx.stroke();
    //   }
    //   //绘制横线
    //   for (var i1 = stepy + 0.5; i1 < canvas.height; i1 += stepy) {
    //     ctx.beginPath(); //新的一条路径
    //     ctx.moveTo(0, i1);
    //     ctx.lineTo(canvas.width, i1);
    //     ctx.stroke();
    //   }
    // }
    // drawLine(10, 10);

    // ctx.beginPath();
    // ctx.arc(75, 75, 50, 0, 360 * Math.PI / 180, true); //绘制一个圆
    // //    true ：逆时针
    // ctx.moveTo(110, 75);
    // ctx.arc(75, 75, 35, 0, 180 * Math.PI / 180, false); //口
    // //    false //顺时针
    // ctx.moveTo(65, 65);
    // ctx.arc(60, 65, 5, 0, 360 * Math.PI / 180, true); //左眼
    // ctx.moveTo(95, 65);
    // ctx.arc(90, 65, 5, 0, 360 * Math.PI / 180, true); //右眼
    // // ctx.moveTo(200,330);
    // // ctx.lineTo(230,400);
    // ctx.stroke();

    ctx.moveTo(75, 25);
    ctx.quadraticCurveTo(25, 25, 25, 62.5);
    ctx.quadraticCurveTo(25, 100, 50, 100);
    ctx.quadraticCurveTo(50, 120, 30, 125);
    ctx.quadraticCurveTo(60, 120, 65, 100);
    ctx.quadraticCurveTo(125, 100, 125, 62.5);
    ctx.quadraticCurveTo(125, 25, 75, 25);
    ctx.stroke();

    let width = 5
    ctx.fillRect(75, 25, width, width)
    ctx.fillRect(25, 25, width, width)
    ctx.fillRect(25, 100, width, width)
    ctx.fillRect(50, 120, width, width)
    ctx.fillRect(60, 120, width, width)
    ctx.fillRect(125, 100, width, width)
    ctx.fillRect(125, 25, width, width)
    
</script>
</html>